package org.yzh.web.task;


import com.github.dozermapper.core.Mapper;
import com.ling5821.mtime.Mtime;
import com.qiniu.processing.OperationStatus;
import com.qiniu.storage.model.FileInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.yzh.web.commons.CoordUtils;
import org.yzh.web.component.qiniu.QiniuManager;
import org.yzh.web.model.entity.*;
import org.yzh.web.model.vo.*;
import org.yzh.web.service.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * @author lsj
 * @date 2021/1/16 17:31
 */
@Component
@Slf4j
public class DataAnalysisTask {
    @Autowired
    private DeviceService deviceService;

    @Autowired
    private AlarmMessageService alarmMessageService;

    @Autowired
    private AlarmCountService alarmCountService;

    @Autowired
    private AlarmCountHourService alarmCountHourService;

    @Autowired
    private LocationService locationService;

    @Autowired
    private VehicleTravelService vehicleTravelService;

    @Autowired
    private VideoDownloadService videoDownloadService;

    @Autowired
    private Mapper dozerMapper;

    @Async
    @Scheduled(cron = "0 */20 * * * ?")
    public void alarmCountJob() {
        List<DeviceDO> devices = deviceService.find(new DeviceQuery());
        LocalDateTime now = LocalDateTime.now();
        for (DeviceDO device : devices) {
            AlarmMessageQuery query = new AlarmMessageQuery();
            query.setPlateNo(device.getPlateNo());
            query.setStartDateTime(Mtime.startOfDay(now));
            query.setEndDateTime(Mtime.endOfDay(now));
            AlarmCountTotal alarmCountTotal = alarmMessageService.findAlarmCountTotal(query);
            AlarmCountDO alarmCount = dozerMapper.map(alarmCountTotal, AlarmCountDO.class);
            dozerMapper.map(device, alarmCount);
            alarmCount.setDate(now.toLocalDate());
            alarmCountService.upsert(alarmCount);
            log.info("alarmCountJob update {}", alarmCount.toString());
        }
    }

    @Async
    @Scheduled(cron = "0 0 * * * ?")
    public void alarmCountHourJob() {
        LocalDateTime now = LocalDateTime.now();
        AlarmMessageQuery query = new AlarmMessageQuery();
        LocalDateTime startDateTime = Mtime.minusHour(now);
        LocalDateTime endDateTime = Mtime.nowHour(now);
        query.setStartDateTime(Mtime.minusHour(now));
        query.setEndDateTime(Mtime.nowHour(now));
        AlarmCountTotal alarmCountTotal = alarmMessageService.findAlarmCountTotal(query);
        AlarmCountHourDO countHourDO = new AlarmCountHourDO();
        countHourDO.setDate(startDateTime.toLocalDate());
        countHourDO.setStartHour(startDateTime.toLocalTime());
        countHourDO.setEndHour(endDateTime.toLocalTime());
        int total = alarmCountTotal.getFcwCount() + alarmCountTotal.getUfcwCount() + alarmCountTotal.getPcwCount()
            + alarmCountTotal.getLdwlCount() + alarmCountTotal.getLdwrCount() + alarmCountTotal.getHmwCount();
        countHourDO.setCount(total);
        log.info("alarmCountHourJob {}", countHourDO);
        alarmCountHourService.upsert(countHourDO);
    }

    @Async
    @Scheduled(cron = "0 */20 * * * ?")
    public void calcMileageJob() {
        List<DeviceDO> devices = deviceService.find(new DeviceQuery());
        LocalDateTime now = LocalDateTime.now();
        for (DeviceDO device : devices) {
            LocationQuery query = new LocationQuery();
            query.setDeviceId(device.getDeviceId());
            query.setPlateNo(device.getPlateNo());
            query.setDate(now.toLocalDate());
            List<Location> locations = locationService.find(query);
            if (locations.size() <= 0) {
                continue;
            }
            Location startLocation = locations.get(0);
            double distance = 0;
            for (Location location : locations) {
                if (startLocation.getLatitude() == null || startLocation.getLongitude() == null
                    || location.getLongitude() == null || location.getLatitude() == null) {
                    startLocation = location;
                    continue;
                }
                distance += CoordUtils
                    .distance(startLocation.getLongitude(), startLocation.getLatitude(), location.getLongitude(),
                        location.getLatitude());
            }

            Optional<VehicleTravelDO>
                unique = vehicleTravelService.findUnique(device.getDeviceId(), device.getPlateNo(), now.toLocalDate());
            if (unique.isPresent()) {
                VehicleTravelDO record = unique.get();
                record.setTravelMileage(distance);
                vehicleTravelService.update(record);
                log.info("calcMileageJob update {}", record);
            } else {
                VehicleTravelDO record = new VehicleTravelDO();
                record.setDate(now.toLocalDate());
                record.setTravelMileage(distance);
                record.setTravelTime(0);
                record.setDeviceId(device.getDeviceId());
                record.setMobileNo(device.getMobileNo());
                record.setPlateNo(device.getPlateNo());
                vehicleTravelService.insert(record);
                log.info("calcMileageJob insert {}", record);
            }
        }
    }

    @Async
    @Scheduled(fixedDelay = 2000, initialDelay = 1000)
    public void updateVideoDownloadJob() {
        videoDownloadService.updateVideoDownloadStatus();
    }

}
